import { GameObject } from '@/assets/scripts/GameObject.js'

/**
 * 技能类，继承自GameObject基类
 * 所有技能的父类
 */
export class SkillBase extends GameObject {
    /**
     * 构造函数
     * @param {Object} player 使用该技能的玩家对象
     * @param {number} cooldown 技能设计冷却时间(秒)
     */
    constructor(player, cooldown) {
        super()
        try {
            this.player = player || null
            // 确保gameMap初始化正确
            this.gameMap = player ? player.gameMap : null
            
            // 如果没有有效的gameMap，尝试等待gameMap初始化
            if (!this.gameMap && player) {
                // 创建一个定时器尝试获取gameMap，最多尝试5次，每次间隔100ms
                let attempts = 0;
                const maxAttempts = 5;
                const checkGameMap = () => {
                    attempts++;
                    if (player.gameMap) {
                        this.gameMap = player.gameMap;
                    } else if (attempts < maxAttempts) {
                        setTimeout(checkGameMap, 100);
                    }
                };
                setTimeout(checkGameMap, 100);
            }
            
            this.cooldown = cooldown * 1000 // 将秒转为毫秒
            this.designedCooldown = cooldown
            this.lastCastTime = 0
            this.remainingCooldown = 0 // 剩余冷却时间(毫秒)
            this.eps = 0.1
            this.skillKey = ''
            this.skillName = ''
            this.skillIcon = null
            this.skillIconLoaded = false
            this._logErrors = {}  // 用于控制错误日志只输出一次
        } catch (error) {
            console.error('技能初始化错误:', error);
        }
    }

    // 判断技能是否在冷却中
    is_on_cooldown() {
        const currentTime = new Date().getTime()
        // 使用时间差判断或remainingCooldown判断，确保两种方式都考虑到
        return (currentTime - this.lastCastTime) < this.cooldown || this.remainingCooldown > 0
    }

    // 更新冷却时间
    update_cooldown(timeDelta) {
        // 更新剩余冷却时间，而不是减少总冷却时间
        if (this.remainingCooldown > 0) {
            this.remainingCooldown -= timeDelta
            this.remainingCooldown = Math.max(0, this.remainingCooldown)
        } else {
            // 使用时间戳计算剩余冷却时间
            const currentTime = new Date().getTime()
            const elapsedTime = currentTime - this.lastCastTime
            this.remainingCooldown = Math.max(0, this.cooldown - elapsedTime)
        }
    }

    // 重置冷却
    reset_cooldown() {
        this.lastCastTime = new Date().getTime()
        this.remainingCooldown = this.cooldown // 重置剩余冷却时间
    }

    // 加载技能图标
    load_icon(iconUrl) {
        this.skillIcon = new Image()
        this.skillIcon.src = iconUrl
        this.skillIcon.onload = () => {
            this.skillIconLoaded = true // 图标加载完成后设置标志
        }
    }

    // 施放技能
    cast() {
        // 如果技能在冷却中，返回失败
        if (this.is_on_cooldown()) return false

        // 重置冷却时间
        this.reset_cooldown()
        return true
    }

    // 继承自GameObject的update方法，用于更新技能冷却时间
    update() {
        super.update()
        // 更新技能状态
        this.update_cooldown(this.timeDelta)
    }

    // 绘制技能图标
    draw_skill_icon(x, y, r, scale) {
        try {
            // 检查必要的gameMap和ctx是否存在
            if (!this.gameMap) {
                // 尝试从player获取gameMap
                if (this.player && this.player.gameMap) {
                    this.gameMap = this.player.gameMap;
                } else {
                    if (!this._logErrors.noGameMap) {
                        console.warn(`技能 ${this.skillName} 绘制图标失败: gameMap不存在`);
                        this._logErrors.noGameMap = true;
                    }
                    return;
                }
            }
            
            // 确保ctx存在
            if (!this.gameMap.ctx) {
                if (!this._logErrors.noCtx) {
                    console.warn(`技能 ${this.skillName} 绘制图标失败: ctx不存在`);
                    this._logErrors.noCtx = true;
                }
                return;
            }
            
            // 检查参数有效性
            if (!scale || x === undefined || y === undefined || r === undefined) {
                if (!this._logErrors.invalidParams) {
                    console.warn(`技能 ${this.skillName} 绘制图标失败: 参数无效`);
                    this._logErrors.invalidParams = true;
                }
                return;
            }
            
            // 如果图标未加载，使用备用图标
            if (!this.skillIconLoaded) {
                this.gameMap.ctx.beginPath();
                this.gameMap.ctx.arc(x * scale, y * scale, r * scale, 0, Math.PI * 2);
                this.gameMap.ctx.fillStyle = 'rgba(50, 50, 50, 0.8)';
                this.gameMap.ctx.fill();
                this.gameMap.ctx.strokeStyle = 'rgba(200, 200, 200, 0.8)';
                this.gameMap.ctx.stroke();
                
                // 尝试在图标中央显示技能名称首字母
                if (this.skillName) {
                    this.gameMap.ctx.fillStyle = 'white';
                    this.gameMap.ctx.textAlign = 'center';
                    this.gameMap.ctx.textBaseline = 'middle';
                    this.gameMap.ctx.font = `bold ${r * scale * 0.8}px Arial`;
                    this.gameMap.ctx.fillText(this.skillName.charAt(0).toUpperCase(), x * scale, y * scale);
                }
                return;
            }

            // 绘制技能图标(圆形裁剪)
            this.gameMap.ctx.save();
            this.gameMap.ctx.beginPath();
            this.gameMap.ctx.arc(x * scale, y * scale, r * scale, 0, Math.PI * 2);
            this.gameMap.ctx.strokeStyle = 'rgba(200, 200, 200, 0.8)';
            this.gameMap.ctx.stroke();
            this.gameMap.ctx.clip();
            
            try {
                this.gameMap.ctx.drawImage(
                    this.skillIcon,
                    (x - r) * scale,
                    (y - r) * scale,
                    r * 2 * scale,
                    r * 2 * scale
                );
            } catch (imgError) {
                console.warn(`技能 ${this.skillName} 图标绘制失败:`, imgError);
                // 使用备用颜色
                this.gameMap.ctx.fillStyle = 'rgba(100, 100, 100, 0.8)';
                this.gameMap.ctx.fillRect((x - r) * scale, (y - r) * scale, r * 2 * scale, r * 2 * scale);
            }
            
            this.gameMap.ctx.restore();

            // 在图标下方绘制快捷键文本
            this.gameMap.ctx.font = `${r * 0.8 * scale}px Arial`;
            this.gameMap.ctx.fillStyle = 'white';
            this.gameMap.ctx.textAlign = 'center';
            this.gameMap.ctx.fillText(this.skillKey, x * scale, (y + r * 1.5) * scale);

            // 如果技能在冷却中，绘制冷却遮罩
            if (this.is_on_cooldown()) {
                // 计算已过去的冷却时间比例
                const currentTime = new Date().getTime();
                const elapsedTime = currentTime - this.lastCastTime;
                const cooldownRatio = Math.min(1, elapsedTime / this.cooldown);
                
                // 绘制冷却扇形
                this.gameMap.ctx.beginPath();
                this.gameMap.ctx.moveTo(x * scale, y * scale);
                // 绘制扇形遮罩(从12点方向顺时针减少)
                this.gameMap.ctx.arc(
                    x * scale,
                    y * scale,
                    r * scale,
                    -Math.PI / 2,
                    -Math.PI / 2 + Math.PI * 2 * (1 - cooldownRatio),
                    false
                );
                this.gameMap.ctx.closePath();
                this.gameMap.ctx.fillStyle = 'rgba(40, 40, 40, 0.6)'; // 半透明黑色遮罩
                this.gameMap.ctx.fill();
                
                // 显示剩余冷却时间
                const remainingSeconds = Math.ceil((this.cooldown - elapsedTime) / 1000);
                if (remainingSeconds > 0) {
                    this.gameMap.ctx.fillStyle = 'white';
                    this.gameMap.ctx.textAlign = 'center';
                    this.gameMap.ctx.textBaseline = 'middle';
                    this.gameMap.ctx.font = `bold ${r * scale * 0.7}px Arial`;
                    this.gameMap.ctx.fillText(remainingSeconds.toString(), x * scale, y * scale);
                }
            }
        } catch (error) {
            if (!this._logErrors.renderError) {
                console.error(`技能 ${this.skillName} 图标渲染出错:`, error);
                this._logErrors.renderError = true;
            }
        }
    }
}
